<?php
/**
 * Main class for the Cerberus Framework
 *
 * @author André Silva
 */
class Cerberus {
	/**
	 * Current action
	 * @var PublicController
	 */
	private static $controller;
	/**
	 * Loaded modules
	 * @var array
	 */
	private static $modules = array();

	/**
	 * Returns the current action
	 * @return PublicAction
	 */
	public static function &getController() {
		return self::$controller;
	}

	/**
	 * Retorna o caminho da action executada
	 *
	 * @return string
	 */
	public static function getControllerName() {
		return ucfirst(!empty($_GET['action']) ? $_GET['action'] : APPLICATION_HOME);
	}

	/**
	 * Load all modules from the configuration file
	 */
	public static function loadConfiguration() {
		$config = include(APPLICATION_PATH.DIRECTORY_SEPARATOR.'config.php');
		if (is_array($config)) {
			foreach ($config as $class => $atributes) {
				$className = import($class);
				$method = new ReflectionMethod($className, 'start');
				$method->invoke(null, $atributes);
				array_push(self::$modules, $className);
			}
		}
	}

	/**
	 * Begin the request
	 */
	public static function start() {
		self::loadConfiguration();

		$controllerName = self::getControllerName();
		import('application.controllers.'.$controllerName);

		if (!class_exists($controllerName)) {
			throw new Exception('Action not found: ' . $controllerName);
		}

		self::$controller = new $controllerName();
		self::$controller->execute();
	}

	/**
	 * Finish the request
	 * @param boolean $flush
	 */
	public static function finish($flush = true) {
		self::$controller->onFinish();

		if($flush) {
			echo self::$controller->getBuffer();
		}

		foreach (self::$modules as $module) {
			$method = new ReflectionMethod($module, 'finish');
			$method->invoke(null, null);
		}
	}

	/**
	 * Translate a virtual path for a real path
	 * @param string $param
	 * @param boolean $preserve_last
	 * @return string
	 */
	public static function resolvePath($param, $preserve_last = false) {
		$path = null;
		$pieces = explode('.', $param);
		if (!$preserve_last) {
			array_pop($pieces);
		}

		if (count($pieces)>0) {
			if ($pieces[0] == CERBERUS_ALIAS) {
				array_shift($pieces);
				$path = CERBERUS_PATH;
			} else if ($pieces[0] == APPLICATION_ALIAS) {
				array_shift($pieces);
				$path = APPLICATION_PATH;
			} else {
				$path = APPLICATION_ROOT;
			}
		} else {
			$path = APPLICATION_ROOT;
		}
		return $path.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $pieces);
	}

	/**
	 * Check if a class implements the interface
	 * @param string $className
	 * @param string $interface
	 * @return boolean
	 */
	public static function hasInterface($className, $interface) {
		$class = new ReflectionClass($className);
		return $class->implementsInterface($interface);
	}

	/**
	 * Return the value for the class constant
	 * @param string $className
	 * @param string $constant
	 * @return mixed
	 */
	public static function getConstant($className, $constant) {
		$class = new ReflectionClass($className);
		return $class->getConstant($constant);
	}

	/**
	 * Return the value for the class static property
	 * @param string $className
	 * @param string $property
	 * @return mixed
	 */
	public static function getStaticProperty($className, $property) {
		$class = new ReflectionClass($className);
		return $class->getStaticPropertyValue($property);
	}
}
?>
